package org.itzheng.ui.popup;

import android.app.Activity;
import android.content.Context;
import android.graphics.Point;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.view.Display;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.PopupWindow;

import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;

/**
 * Title:<br>
 * Description: <br>
 *
 * @email ItZheng@ZoHo.com
 * Created by itzheng on 2017/8/4.
 */
public class BasePopupWindow extends PopupWindow {
    private Context mContext;

    public Context getContext() {
        return mContext;
    }

    public BasePopupWindow(Context context) {
        super(context);
        mContext = context;
        {   //距离顶部状态栏
            setClippingEnabled(false);
        }

        {   //设置点击外部关闭
            setOutsideTouchable(true);
            setBackgroundDrawable(new ColorDrawable());
        }
        {//设置宽高，如果不设置，OPPO 不能正确显示
            setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
            setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
        }
        //当用户有底部虚拟导航栏的时候，自动距离底部虚拟导航栏
//        setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
//        setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
//        setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
//        setBackgroundDrawable(new BitmapDrawable());
////        setBackgroundDrawable(new ColorDrawable(UIUtils.getColor(R.color.colorBlack_5p)));
//        setOutsideTouchable(true);
    }

    protected View inflate(@LayoutRes int resource) {
        return LayoutInflater.from(getContext()).inflate(resource, null);
    }

    /**
     * 是否可取消
     */
    protected boolean mCancelable = false;
    /**
     * 取消监听，理论上，界面上的取消按钮和这个的效果一样
     */
    protected OnCancelListener mOnCancelListener;

    public void setCancelable(boolean cancelable) {
        mCancelable = cancelable;
    }

    public void setOnCancelListener(OnCancelListener listener) {
        mOnCancelListener = listener;
    }

    /**
     * 是否拦截返回键，需要外界主动调用判断，已经在初始化时put了
     * setFocusable(true) 可以直接在Activity中拦截onBackPressed
     *
     * @return
     */
    public boolean onBackPressed() {
        if (isShowing()) {
            //如果正在显示，则拦截事件。如果可以取消则取消
            if (mCancelable) {
                if (mOnCancelListener != null) {
                    mOnCancelListener.onCancel(this);
                }
                dismiss();
            }
            return true;
        }
        return false;
    }

    /**
     * 取消的监听，用户按返回键，如果可以返回的话，执行
     */
    public interface OnCancelListener {
        void onCancel(BasePopupWindow basePopupWindow);
    }

    /**
     * 判断底部导航栏是否显示，这个方式，当全面手势时，方法无效
     *
     * @param act
     * @return
     */
    private static boolean isNavigationBarShow(Activity act) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            Display display = act.getWindowManager().getDefaultDisplay();
            Point size = new Point();
            Point realSize = new Point();
            display.getSize(size);
            display.getRealSize(realSize);
            return realSize.y != size.y;
        } else {
            boolean menu = ViewConfiguration.get(act).hasPermanentMenuKey();
            boolean back = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
            if (menu || back) {
                return false;
            } else {
                return true;
            }
        }
    }

    /**
     * 如果有底部导航栏 获取底部导航栏高度
     *
     * @param context
     * @return
     */
    private static int getBottomNavigatorHeight(Context context) {
        int rid = context.getResources().getIdentifier("config_showNavigationBar", "bool", "android");
        if (0 != rid) {
            int resourceId = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
            return context.getResources().getDimensionPixelSize(resourceId);
        }
        return 0;
    }

    private static final String NAVIGATION = "navigationBarBackground";


    /**
     * 判断是否有底部虚拟导航栏
     * 该方法需要在View完全被绘制出来之后调用，否则判断不了
     * 在比如 onWindowFocusChanged（）方法中可以得到正确的结果
     *
     * @param activity
     * @return
     */
    public static boolean isNavigationBarExist(@NonNull Activity activity) {
        ViewGroup vp = (ViewGroup) activity.getWindow().getDecorView();
        if (vp != null) {
            for (int i = 0; i < vp.getChildCount(); i++) {
                vp.getChildAt(i).getContext().getPackageName();
                if (vp.getChildAt(i).getId() != View.NO_ID && NAVIGATION.equals(activity.getResources().getResourceEntryName(vp.getChildAt(i).getId()))) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 底部弹出差值，就是判断是否有虚拟导航栏
     *
     * @param activity
     * @return
     */
    public static int getBottomOffset(Activity activity) {
        if (isNavigationBarShow(activity) && isNavigationBarExist(activity)) {
            //因为第一个方式，在全面屏是，如果手机支持虚拟导航，会误判，所以加了第二种方式
            int navHeight = getBottomNavigatorHeight(activity);
            if (navHeight < 0) {
                navHeight = 0;
            }
            return navHeight;
        } else {
            return 0;
        }
    }

}
